@typeparam TItem
@using Microsoft.AspNetCore.Components.Forms
 <CascadingValue Value=@EditContext>
    <CascadingValue Value=Row>
@if (Grid.AllowCompositeDataCells ? RowIndex == Column.GetLevel() : (Column.Parent != null && RowIndex == Column.GetLevel() ||  Column.Columns == null))
{
<td rowspan="@(Column.GetRowSpan(true))" colspan="@(Column.GetColSpan(true))" @attributes="@Attributes" style="@GetStyle()" class="@GetCssClass()" @onclick="@OnClick" @ondblclick="@OnDblClick" @oncontextmenu="@OnContextMenu" @oncontextmenu:preventDefault="@Grid.CellContextMenu.HasDelegate">
    <CascadingValue Value=this>
        @ChildContent
    </CascadingValue>
</td>
}
else
{
    @foreach(var column in Grid.childColumns.Where(c => c.GetVisible() && c.Parent == Column))
    {
        <RadzenDataGridCell Row=@Row EditContext=EditContext RowIndex="@RowIndex" Grid="@Grid" Column="@column" Item="@Item"
            Style="@column.GetStyle(true)" CssClass="@(column.CssClass + " " + Grid.getFrozenColumnClass(column, Grid.ColumnsCollection) + " " + Grid.getCompositeCellCSSClass(column))" Attributes="@(Grid.CellAttributes(Item, column))">
                @if (Grid.Responsive)
                {
                    <span class="rz-column-title">
                        @if (column.HeaderTemplate != null)
                        {
                            @column.HeaderTemplate
                        }
                        else
                        {
                            @column.GetTitle()
                        }
                    </span>
                }
                <span class="rz-cell-data" title="@(column.Template == null && Grid.ShowCellDataAsTooltip ? column.GetValue(Item) : "")">
                    @if (Item != null)
                    {
                        @if (Grid.IsRowInEditMode(Item) && column.EditTemplate != null)
                        {
                            @column.EditTemplate(Item)
                        }
                        else if (column.Template != null)
                        {
                            @column.Template(Item)
                        }
                        else
                        {
                            @column.GetValue(Item)
                        }
                    }
                </span>
            </RadzenDataGridCell>
    }
}
 </CascadingValue>
</CascadingValue>
@code {
    [Parameter(CaptureUnmatchedValues = true)]
    public IReadOnlyDictionary<string, object> Attributes { get; set; }

    [Parameter]
    public int RowIndex { get; set; }

    [Parameter]
    public RadzenDataGridRow<TItem> Row { get; set; }

    [Parameter]
    public EditContext EditContext { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Parameter]
    public string CssClass { get; set; }

    [Parameter]
    public string Style { get; set; }

    [Parameter]
    public TItem Item { get; set; }

    [Parameter]
    public RadzenDataGridColumn<TItem> Column { get; set; }

    [Parameter]
    public RadzenDataGrid<TItem> Grid { get; set; }

    async Task OnContextMenu(MouseEventArgs args)
    {
        if (Grid != null)
        {
#if NET5_0_OR_GREATER
            await Grid.OnCellContextMenu(new DataGridCellMouseEventArgs<TItem>
            {
                Data = Item,
                AltKey = args.AltKey,
                Button = args.Button,
                Buttons = args.Buttons,
                ClientX = args.ClientX,
                ClientY = args.ClientY,
                CtrlKey = args.CtrlKey,
                Detail = args.Detail,
                MetaKey = args.MetaKey,
                OffsetX = args.OffsetX,
                OffsetY = args.OffsetY,
                ScreenX = args.ScreenX,
                ScreenY = args.ScreenY,
                ShiftKey = args.ShiftKey,
                Type = args.Type,
                Column = Column
            });
#else
            await Grid.OnCellContextMenu(new DataGridCellMouseEventArgs<TItem>
            {
                Data = Item,
                AltKey = args.AltKey,
                Button = args.Button,
                Buttons = args.Buttons,
                ClientX = args.ClientX,
                ClientY = args.ClientY,
                CtrlKey = args.CtrlKey,
                Detail = args.Detail,
                MetaKey = args.MetaKey,
                ScreenX = args.ScreenX,
                ScreenY = args.ScreenY,
                ShiftKey = args.ShiftKey,
                Type = args.Type,
                Column = Column
            });
#endif
        }
    }

    bool clicking;
    async Task OnClick(MouseEventArgs args)
    {
        if (clicking)
        {
            return;
        }
            try
            {
                clicking = true;
        if (Grid != null)
        {
#if NET5_0_OR_GREATER
            await Grid.OnCellClick(new DataGridCellMouseEventArgs<TItem>
            {
                Data = Item,
                AltKey = args.AltKey,
                Button = args.Button,
                Buttons = args.Buttons,
                ClientX = args.ClientX,
                ClientY = args.ClientY,
                CtrlKey = args.CtrlKey,
                Detail = args.Detail,
                MetaKey = args.MetaKey,
                OffsetX = args.OffsetX,
                OffsetY = args.OffsetY,
                ScreenX = args.ScreenX,
                ScreenY = args.ScreenY,
                ShiftKey = args.ShiftKey,
                Type = args.Type,
                Column = Column
            });
#else
            await Grid.OnCellClick(new DataGridCellMouseEventArgs<TItem>
            {
                Data = Item,
                AltKey = args.AltKey,
                Button = args.Button,
                Buttons = args.Buttons,
                ClientX = args.ClientX,
                ClientY = args.ClientY,
                CtrlKey = args.CtrlKey,
                Detail = args.Detail,
                MetaKey = args.MetaKey,
                ScreenX = args.ScreenX,
                ScreenY = args.ScreenY,
                ShiftKey = args.ShiftKey,
                Type = args.Type,
                Column = Column
            });
#endif
#if NET5_0_OR_GREATER
            await Grid.OnRowClick(new DataGridRowMouseEventArgs<TItem>
            {
                Data = Item,
                AltKey = args.AltKey,
                Button = args.Button,
                Buttons = args.Buttons,
                ClientX = args.ClientX,
                ClientY = args.ClientY,
                CtrlKey = args.CtrlKey,
                Detail = args.Detail,
                MetaKey = args.MetaKey,
                OffsetX = args.OffsetX,
                OffsetY = args.OffsetY,
                ScreenX = args.ScreenX,
                ScreenY = args.ScreenY,
                ShiftKey = args.ShiftKey,
                Type = args.Type
            });
#else
            await Grid.OnRowClick(new DataGridRowMouseEventArgs<TItem>
            {
                Data = Item,
                AltKey = args.AltKey,
                Button = args.Button,
                Buttons = args.Buttons,
                ClientX = args.ClientX,
                ClientY = args.ClientY,
                CtrlKey = args.CtrlKey,
                Detail = args.Detail,
                MetaKey = args.MetaKey,
                ScreenX = args.ScreenX,
                ScreenY = args.ScreenY,
                ShiftKey = args.ShiftKey,
                Type = args.Type
            });
#endif
            }
        }
        finally
        {
            clicking = false;
        }
    }

    async Task OnDblClick(MouseEventArgs args)
    {
        if (Grid != null)
        {
#if NET5_0_OR_GREATER
            await Grid.OnCellDblClick(new DataGridCellMouseEventArgs<TItem>
            {
                Data = Item,
                AltKey = args.AltKey,
                Button = args.Button,
                Buttons = args.Buttons,
                ClientX = args.ClientX,
                ClientY = args.ClientY,
                CtrlKey = args.CtrlKey,
                Detail = args.Detail,
                MetaKey = args.MetaKey,
                OffsetX = args.OffsetX,
                OffsetY = args.OffsetY,
                ScreenX = args.ScreenX,
                ScreenY = args.ScreenY,
                ShiftKey = args.ShiftKey,
                Type = args.Type,
                Column = Column
            });
#else
            await Grid.OnCellDblClick(new DataGridCellMouseEventArgs<TItem>
            {
                Data = Item,
                AltKey = args.AltKey,
                Button = args.Button,
                Buttons = args.Buttons,
                ClientX = args.ClientX,
                ClientY = args.ClientY,
                CtrlKey = args.CtrlKey,
                Detail = args.Detail,
                MetaKey = args.MetaKey,
                ScreenX = args.ScreenX,
                ScreenY = args.ScreenY,
                ShiftKey = args.ShiftKey,
                Type = args.Type,
                Column = Column
            });
#endif
#if NET5_0_OR_GREATER
            await Grid.OnRowDblClick(new DataGridRowMouseEventArgs<TItem>
            {
                Data = Item,
                AltKey = args.AltKey,
                Button = args.Button,
                Buttons = args.Buttons,
                ClientX = args.ClientX,
                ClientY = args.ClientY,
                CtrlKey = args.CtrlKey,
                Detail = args.Detail,
                MetaKey = args.MetaKey,
                OffsetX = args.OffsetX,
                OffsetY = args.OffsetY,
                ScreenX = args.ScreenX,
                ScreenY = args.ScreenY,
                ShiftKey = args.ShiftKey,
                Type = args.Type
            });
#else
            await Grid.OnRowDblClick(new DataGridRowMouseEventArgs<TItem>
            {
                Data = Item,
                AltKey = args.AltKey,
                Button = args.Button,
                Buttons = args.Buttons,
                ClientX = args.ClientX,
                ClientY = args.ClientY,
                CtrlKey = args.CtrlKey,
                Detail = args.Detail,
                MetaKey = args.MetaKey,
                ScreenX = args.ScreenX,
                ScreenY = args.ScreenY,
                ShiftKey = args.ShiftKey,
                Type = args.Type
            });
#endif
        }
    }

    string GetCssClass()
    {
        if (Attributes != null && Attributes.TryGetValue("class", out var @class) && !string.IsNullOrEmpty(Convert.ToString(@class)))
        {
            return $"{CssClass} {@class}".Trim();
        }

        return String.IsNullOrWhiteSpace(CssClass) ? null : CssClass;
    }

    string GetStyle()
    {
        if (Attributes != null && Attributes.TryGetValue("style", out var style) == true && !string.IsNullOrEmpty(Convert.ToString(style)))
        {
            return String.IsNullOrEmpty(Style) ? $"{style}" : $"{Style.TrimEnd(';')};{style}";
        }

        return Style;
    }
}